﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Web.Security;

namespace TerryDong.Core
{
    public class SecurityHelper
    {
        public enum EncryptType
        {
            MD5, DES
        }

        /// <summary>
        /// default const key for encrypt or decrypt,"TerryDong"
        /// </summary>
        private const string _defaultKey = "TerryDong";

        #region Methods

        /// <summary>
        /// decrypt the encypted byte[] using default key "TerryDong" From MD5 model
        /// </summary>
        /// <param name="encrypted"> the encrypted byte[]</param>
        /// <returns>the decrypted byte[]</returns>
        public static byte[] DecryptFromMD5(byte[] encrypted)
        {
            byte[] bytes = Encoding.Default.GetBytes(_defaultKey);
            return DecryptFromMD5(encrypted, bytes);
        }

        /// <summary>
        /// decrypt the encypted string using default key "TerryDong" From MD5
        /// </summary>
        /// <param name="original">the encrypeted string</param>
        /// <returns>the decrypted string</returns>
        public static string Decrypt(string original)
        {
            return Decrypt(original, _defaultKey);
        }

        /// <summary>
        /// decrypt the encypted byte[] using the given key  From MD5 model
        /// </summary>
        /// <param name="encrypted">the encrypted byte[]</param>
        /// <param name="key">given key</param>
        /// <returns>the decrypted byte[]</returns>
        public static byte[] DecryptFromMD5(byte[] encrypted, byte[] key)
        {
            TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
            provider.Key = MakeMD5(key);
            provider.Mode = CipherMode.ECB;
            return provider.CreateDecryptor().TransformFinalBlock(encrypted, 0, encrypted.Length);
        }

        /// <summary>
        /// decrypt the encypted string using the given key From MD5
        /// </summary>
        /// <param name="original">the encypted string</param>
        /// <param name="key">given key</param>
        /// <returns>the decrypted string</returns>
        public static string Decrypt(string original, string key)
        {
            byte[] buffer = Convert.FromBase64String(original);
            byte[] bytes = Encoding.Default.GetBytes(key);
            return Encoding.Default.GetString(DecryptFromMD5(buffer, bytes));
        }


        /// <summary>
        /// encrypt string using the default key "TerryDong" as MD5 string.
        /// </summary>
        /// <param name="original">the orginal text</param>
        /// <returns>the encrypt text</returns>
        public static string Encrypt(string original)
        {
            return Encrypt(original, _defaultKey);
        }

        /// <summary>
        /// encrypt string using the default key "TerryDong"
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public static byte[] EncryptToMD5(byte[] original)
        {
            byte[] bytes = Encoding.Default.GetBytes(_defaultKey);
            return EncryptToMD5(original, bytes);
        }

        /// <summary>
        /// encrypt string using the given key as MD5 string.
        /// </summary>
        /// <param name="original">orginal text</param>
        /// <param name="key">key for encrypt</param>
        /// <returns>the encrypted text</returns>
        public static string Encrypt(string original, string key)
        {
            byte[] bytes = Encoding.Default.GetBytes(original);
            byte[] buffer2 = Encoding.Default.GetBytes(key);
            return Convert.ToBase64String(EncryptToMD5(bytes, buffer2));
        }

        /// <summary>
        /// encypt orginal byte[] using the given key as MD5 model
        /// </summary>
        /// <param name="original"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] EncryptToMD5(byte[] original, byte[] key)
        {
            TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
            provider.Key = MakeMD5(key);
            provider.Mode = CipherMode.ECB;
            return provider.CreateEncryptor().TransformFinalBlock(original, 0, original.Length);
        }

        /// <summary>
        /// make priginal byte[] to MD5 byte[]
        /// </summary>
        /// <param name="original">the original byte[]</param>
        /// <returns>the md5 byte[]</returns>
        public static byte[] MakeMD5(byte[] original)
        {
            byte[] buffer = new MD5CryptoServiceProvider().ComputeHash(original);
            return buffer;
        }

        public static byte[] MakeSHA1(byte[] orginal)
        {
            byte[] buffer = new SHA1CryptoServiceProvider().ComputeHash(orginal);
            return buffer;
        }
        #region
        //public static byte[] EncryptToSHA1(byte[] orginal, byte[] key)
        //{

        //    TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
        //    provider.Key = MakeSHA1(key);
        //    provider.Mode = CipherMode.ECB;
        //    return provider.CreateEncryptor().TransformFinalBlock(orginal, 0, orginal.Length);
        //}


        //public static byte[] EncryptToSHA1(byte[] orginal)
        //{
        //    return EncryptToSHA1(orginal,Encoding.Default.GetBytes(_defaultKey));
        //}

        //public static byte[] DecryptFromSHA1(byte[] encrypted, byte[] key)
        //{
        //    TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
        //    provider.Key = MakeSHA1(key);
        //    provider.Mode = CipherMode.ECB;
        //    return provider.CreateDecryptor().TransformFinalBlock(encrypted, 0, encrypted.Length);
        //}

        //public static byte[] DecryptFromSHA1(byte[] encrypted)
        // {
        //     return DecryptFromSHA1(encrypted,Encoding.Default.GetBytes(_defaultKey));
        //}
        #endregion
        public static string Encrypt(string orginal, EncryptType encryptType)
        {
            string reval = string.Empty;
            switch (encryptType)
            {
                case EncryptType.MD5:
                    reval = Encrypt(orginal);
                    break;
                case EncryptType.DES:
                    reval = EncryptToDES(orginal);
                    break;
                //case EncryptType.SHA1:
                //    reval= Encoding.Default.GetString(EncryptToSHA1(Encoding.Default.GetBytes(orginal)));
                //    break;
            }
            return reval;
        }

        public static string Decrypt(string orginal, EncryptType encryptType)
        {
            string reval = string.Empty;
            switch (encryptType)
            {
                case EncryptType.MD5:
                    reval = Decrypt(orginal);
                    break;
                case EncryptType.DES:
                    reval = DecryptFromDES(orginal);
                    break;
                //case EncryptType.SHA1:
                //    reval = Encoding.Default.GetString(DecryptFromSHA1(Encoding.Default.GetBytes(orginal)));
                //    break;
            }
            return reval;
        }


        #region DES encrypt and decrypt
        public static string DecryptFromDES(string Text)
        {
            return DecryptFromDES(Text, _defaultKey);

        }
        public static string DecryptFromDES(string Text, string sKey)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            int num = Text.Length / 2;
            byte[] buffer = new byte[num];
            for (int i = 0; i < num; i++)
            {
                int num3 = Convert.ToInt32(Text.Substring(i * 2, 2), 0x10);
                buffer[i] = (byte)num3;
            }
            provider.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            provider.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(), CryptoStreamMode.Write);
            stream2.Write(buffer, 0, buffer.Length);
            stream2.FlushFinalBlock();
            return Encoding.Default.GetString(stream.ToArray());
        }

        public static string EncryptToDES(string Text)
        {
            return EncryptToDES(Text, _defaultKey);
        }

        public static string EncryptToDES(string Text, string sKey)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] bytes = Encoding.Default.GetBytes(Text);
            provider.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            provider.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);
            stream2.Write(bytes, 0, bytes.Length);
            stream2.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            foreach (byte num in stream.ToArray())
            {
                builder.AppendFormat("{0:X2}", num);
            }
            return builder.ToString();
        }


        #endregion
        #endregion
    }
    public class HashEncode
    {
        // Methods
        public static string GetRandomValue()
        {
            Random random = new Random();
            return random.Next(1, 0x7fffffff).ToString();//整型数的最大为0x7FFFFFFF，十进制数是2147483647
        }

        public static string GetSecurity()
        {
            return HashEncoding(GetRandomValue());
        }

        public static string HashEncoding(string Security)
        {
            byte[] bytes = new UnicodeEncoding().GetBytes(Security);
            byte[] buffer = new SHA512Managed().ComputeHash(bytes);
            Security = "";
            foreach (byte num in buffer)
            {
                Security = Security + ((int)num) + "O";
            }
            return Security;
        }
    }

    public class RSACryption
    {
        // Methods
        public bool GetHash(FileStream objFile, ref string strHashData)
        {
            byte[] inArray = HashAlgorithm.Create("MD5").ComputeHash(objFile);
            objFile.Close();
            strHashData = Convert.ToBase64String(inArray);
            return true;
        }

        public bool GetHash(FileStream objFile, ref byte[] HashData)
        {
            HashData = HashAlgorithm.Create("MD5").ComputeHash(objFile);
            objFile.Close();
            return true;
        }

        public bool GetHash(string m_strSource, ref string strHashData)
        {
            HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
            byte[] inArray = algorithm.ComputeHash(bytes);
            strHashData = Convert.ToBase64String(inArray);
            return true;
        }

        public bool GetHash(string m_strSource, ref byte[] HashData)
        {
            HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
            HashData = algorithm.ComputeHash(bytes);
            return true;
        }

        public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xmlPrivateKey);
            byte[] rgb = Convert.FromBase64String(m_strDecryptString);
            byte[] bytes = provider.Decrypt(rgb, false);
            return new UnicodeEncoding().GetString(bytes);
        }

        public string RSADecrypt(string xmlPrivateKey, byte[] DecryptString)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xmlPrivateKey);
            byte[] bytes = provider.Decrypt(DecryptString, false);
            return new UnicodeEncoding().GetString(bytes);
        }

        public string RSAEncrypt(string xmlPublicKey, byte[] EncryptString)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xmlPublicKey);
            return Convert.ToBase64String(provider.Encrypt(EncryptString, false));
        }

        public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xmlPublicKey);
            byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
            return Convert.ToBase64String(provider.Encrypt(bytes, false));
        }

        public void RSAKey(out string xmlKeys, out string xmlPublicKey)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            xmlKeys = provider.ToXmlString(true);
            xmlPublicKey = provider.ToXmlString(false);
        }

        public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
        {
            byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPublic);
            RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
            deformatter.SetHashAlgorithm("MD5");
            byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);
            return deformatter.VerifySignature(rgbHash, rgbSignature);
        }

        public bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, string p_strDeformatterData)
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPublic);
            RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
            deformatter.SetHashAlgorithm("MD5");
            byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);
            return deformatter.VerifySignature(HashbyteDeformatter, rgbSignature);
        }

        public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, byte[] DeformatterData)
        {
            byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPublic);
            RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
            deformatter.SetHashAlgorithm("MD5");
            return deformatter.VerifySignature(rgbHash, DeformatterData);
        }

        public bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, byte[] DeformatterData)
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPublic);
            RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
            deformatter.SetHashAlgorithm("MD5");
            return deformatter.VerifySignature(HashbyteDeformatter, DeformatterData);
        }

        public bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref string m_strEncryptedSignatureData)
        {
            byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPrivate);
            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm("MD5");
            byte[] inArray = formatter.CreateSignature(rgbHash);
            m_strEncryptedSignatureData = Convert.ToBase64String(inArray);
            return true;
        }

        public bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref byte[] EncryptedSignatureData)
        {
            byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPrivate);
            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm("MD5");
            EncryptedSignatureData = formatter.CreateSignature(rgbHash);
            return true;
        }

        public bool SignatureFormatter(string p_strKeyPrivate, byte[] HashbyteSignature, ref string m_strEncryptedSignatureData)
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPrivate);
            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm("MD5");
            byte[] inArray = formatter.CreateSignature(HashbyteSignature);
            m_strEncryptedSignatureData = Convert.ToBase64String(inArray);
            return true;
        }

        public bool SignatureFormatter(string p_strKeyPrivate, byte[] HashbyteSignature, ref byte[] EncryptedSignatureData)
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.FromXmlString(p_strKeyPrivate);
            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm("MD5");
            EncryptedSignatureData = formatter.CreateSignature(HashbyteSignature);
            return true;
        }
    }
}
